package gam.n1.be.b;

import gam.n1.areas.Area;
import gam.n1.be.iAsynBehavioral;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Predicate;

public abstract class AsynBehavioral extends BaseBehavioral implements iAsynBehavioral {
    private List<BehavioralTask> taskList;
    private BukkitTask consumer;

    public AsynBehavioral(Area area) {
        super(area);

    }


    @Override
    protected void aP() {
        super.aP();
        if (consumer == null){
            consumer = Bukkit.getScheduler().runTaskTimerAsynchronously(g.plugin(),()->{
                for (BehavioralTask var1 : taskList) {
                    Bukkit.getScheduler().runTaskAsynchronously(g.plugin(),var1.r());
                    taskList.remove(var1);
                }
            },0,20);
        }
    }
    @Override
    public boolean addTask(BehavioralTask runnable) {
        if (taskList == null){
            taskList = Collections.synchronizedList(new LinkedList<>());
        }
        if (runnable.a()){
            return taskList.add(runnable);
        }
        Bukkit.getScheduler().runTaskAsynchronously(g.plugin(), runnable.r());
        return true;
    }


    public final static class BehavioralTask{
        private final boolean a; // delay or direct.
        private final Predicate<Area> b; // whether the task can run.
        private final Runnable r;
        private BehavioralTask(Runnable r,boolean a, Predicate<Area> b){
            this.r = r;
            this.a = a;
            this.b = b;
        }
        public boolean a(){return a;}
        public Predicate<Area> b() {return b;}
        public Runnable r(){return r;}
        public static BehavioralTask build(@NotNull Runnable task, boolean isDelay , Predicate<Area> b){
            if (isDelay) Objects.requireNonNull(b);
            return new BehavioralTask(task,isDelay,b);
        }
    }
    @Override
    public void die() {
        if (!consumer.isCancelled()) consumer.cancel();
    }
}
